/**
 * Copyright 1996 self.com.au
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. (http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
 * the specific language governing permissions and limitations under the License.
 *
 * <dhamma-message src="Atisha (11th century Tibetan Buddhist master)">
 * 	The greatest achievement is selflessness. The greatest worth is self-mastery.
 * 	The greatest quality is seeking to serve others. The greatest precept is continual awareness.
 * 	The greatest medicine is the emptiness of everything. The greatest action is not conforming with the worlds ways.
 * 	The greatest magic is transmuting the passions. The greatest generosity is non-attachment.
 * 	The greatest goodness is a peaceful mind. The greatest patience is humility.
 * 	The greatest effort is not concerned with results. The greatest meditation is a mind that lets go.
 * 	The greatest wisdom is seeing through appearances. 
 * </dhamma-message>
 *
 * @author Ashin Wimalajeewa
 *
 * Note, this is a very old runtime library that I have evolved since 1996. I rarely use it
 * now because the Apache Commons project has made it obsolete.
 */
package self.io;

import java.io.*;

final public class TransferUtils {
  static public String transfer( Class clsThatCanResolveCpResource, String cpResouce ) throws IOException {
    InputStream html = clsThatCanResolveCpResource.getResourceAsStream( cpResouce );
    BufferedInputStream bis = new BufferedInputStream( html, 2048 );
    StringBuffer build = new StringBuffer();
    byte[] buff = new byte[4028];
    int readIn;
    try {
      while ( (readIn = bis.read(buff)) > 0 ) {
        String dat = new String( buff, 0, readIn );
        build.append( dat );
      }
    } finally {
      bis.close();
    }
    return build.toString();
  }

  static public long transfer( Reader rdr, Writer wtr, int buffSize ) throws IOException {
    long ret = 0;
    char[] buff = new char[buffSize];
    BufferedReader br = new BufferedReader( rdr, 2048 );
    try {
      int readIn;
      while ( (readIn = br.read(buff)) > 0 ) {
        ret += readIn;
        wtr.write( buff, 0, readIn );
      }
    } finally {
      br.close();
    }
    return ret;
  }

  static public long transfer( InputStream is, OutputStream os, int buffSize ) throws IOException {
    long ret = 0;
    byte[] buff = new byte[buffSize];
    BufferedInputStream bis = new BufferedInputStream( is, 2048 );
    try {
      int readIn;
      while ( (readIn = bis.read(buff)) > 0 ) {
        ret += readIn;
        os.write( buff, 0, readIn );
      }
    } finally {
      bis.close();
    }
    return ret;
  }

  static public class TemporaryFileOuputStream extends OutputStream {
    File tempFile;
    private FileOutputStream fos;
    private boolean hasClosed;

    public TemporaryFileOuputStream() throws IOException {
        tempFile = File.createTempFile( "tmp.fos", ".trans" );
        fos = new FileOutputStream( tempFile );
    }

    public void close() throws IOException {
      fos.close();
      hasClosed = true;
    }

    public void flush() throws IOException {
      fos.flush();
    }

    public void write(byte b[], int off, int len) throws IOException {
	    fos.write(b, off, len);
    }

    public void write(byte b[]) throws IOException {
      fos.write( b );
    }

    public void write(int b) throws IOException {
      fos.write( b );
    }
    
    public void discard() throws IOException {
    	if (!hasClosed)
    		fos.close();
    	tempFile.delete();
    }
  }

  static public class TemporaryBufferedInputStream extends InputStream {
    private File tempFile;
    private FileInputStream fileStream;
    private BufferedInputStream bufferedStream;
    boolean alreadyClosed;

    public TemporaryBufferedInputStream( TemporaryFileOuputStream tfos ) throws IOException {
      tempFile = tfos.tempFile;
      prepare();
    }
    
    public void prepare() throws IOException {
        close();
        alreadyClosed = false;      
        fileStream = new FileInputStream(tempFile);
        bufferedStream = new BufferedInputStream(fileStream);
    }
    
    public void discard() throws IOException {
        close();
        tempFile.delete();
    }

    public int available() throws IOException {
	    return bufferedStream.available();
    }

    public void close() throws IOException {
      if ( alreadyClosed )
        return;
      alreadyClosed = true;
      if (bufferedStream != null)
    	  bufferedStream.close();
    }

    public synchronized void mark(int readlimit) {
      bufferedStream.mark( readlimit );
    }

    public boolean markSupported() {
	    return bufferedStream.markSupported();
    }

    public int read() throws IOException {
      return bufferedStream.read();
    }

    public int read(byte b[]) throws IOException {
	    return bufferedStream.read( b );
    }

    public int read(byte b[], int off, int len) throws IOException {
      return bufferedStream.read(  b, off, len );
    }

    public synchronized void reset() throws IOException {
      bufferedStream.reset();
    }

    public long skip(long n) throws IOException {
      return bufferedStream.skip( n );
    }
  }
}